#include "shell.h"
#include "command_function.h"

extern char* cmds[];
extern int cmd_count;
extern job* jobs;
extern int* job_count;
extern int job_shmID;

 
void Env_func()
{
   
  extern char ** environ;
   
  for(int i=0;environ[i]!=NULL;i++)
    printf("%s\n",environ[i]);  
}

 
void Add_environ_var(char* str)
{
   
  putenv(str);    
}

 
void Cd_func(int count, int index)
{
  char old_dir[MAX_PATH_LENGTH];
   
  getcwd(old_dir,MAX_PATH_LENGTH);
   
   
  if(count == 1){
     
    printf("%s\n",old_dir);
  }
   
  else if(count > 2)
    fprintf(stderr, RED "[myshell] Error: Too many parameters!\n");
   
  else{
     
    if(!chdir(cmds[index+1]))
      setenv("PWD",cmds[index+1],1);
     
    else
      fprintf(stderr, RED "[myshell] Error: Cannot find directory named %s\n",cmds[index+1]); 
  }
    
}

 
void Clear_func()
{
   
  printf(CLEAR);
}

 
void Pwd_func()
{
  char now_dir[MAX_PATH_LENGTH];
   
  getcwd(now_dir,MAX_PATH_LENGTH);
   
  printf("%s\n",now_dir);
}

 
void Exit_func()
{
   
  exit(0);
}

 
void Time_func()
{
   
  time_t nowtime;
   
  struct tm *t;
   
  char* day[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
   
  time(&nowtime);
  t = localtime(&nowtime);
   
  printf("%d/%d/%d %s %02d:%02d:%02d\n",(1900+t->tm_year),(1+t->tm_mon),t->tm_mday,day[t->tm_wday],t->tm_hour,t->tm_min,t->tm_sec);
}

 
void Umask_func(int count, int index)
{ 
   
  if(count == 1){
     
    mode_t pre_mask;
     
    pre_mask = umask(0);
     
    umask(pre_mask);
     
    printf("%04d\n",pre_mask);
  }
  
   
  else if(count > 2)
    fprintf(stderr, RED "[myshell] Error: umask only need 1 or 0 parameter!\n");
  
   
  else if(strlen(cmds[index + 1]) > 4)
    fprintf(stderr, RED "[myshell] Error: parameter should only be 1 to 4 bit octal number!\n");
  
   
  else{
     
    int flag=0;
     
    for(int i = 0;i < strlen(cmds[index + 1]);i++){
      if(cmds[index + 1][i]=='8' || cmds[index + 1][i]=='9'){
        flag = 1;
        break;
      }
    }
    
     
    if(flag == 0){
      unsigned int new_mask = atoi(cmds[index + 1]) % 1000;
      umask(new_mask);
    }
    
     
    else
      fprintf(stderr, RED "[myshell] Error: the parameter should be octal number!\n");
  }
}

 
void Dir_func(int count, int index)
{
   
  DIR* dir;
   
  struct dirent * ptr;
   
  char path[MAX_PATH_LENGTH];
  
   
  if(count <= 2){
     
    if(count == 1)
       
      getcwd(path,MAX_PATH_LENGTH);
     
    else
      strcpy(path,cmds[index + 1]);
     
    dir = opendir(path);
    while((ptr = readdir(dir)) != NULL){
      if(strcmp(ptr->d_name,".") && strcmp(ptr->d_name,".."))
        printf("%s  ",ptr->d_name);
  }
    printf("\n");
     
    closedir(dir);    
  }
  
   
  else{
    for(int i = 1;i < count;i++){
        strcpy(path,cmds[index + i]);
        dir = opendir(path);
         
        printf("%s:\n",path);
        while((ptr = readdir(dir)) != NULL){
          if(strcmp(ptr->d_name,".") && strcmp(ptr->d_name,".."))
            printf("%s  ",ptr->d_name);
      }
        printf("\n");
        closedir(dir);
    }
  } 
}

 
void Echo_func(int count, int index)
{
   
  for(int i = 1;i < count;i++)
    printf("%s ",cmds[index + i]);
  printf("\n");
}

 
void Exec_func(int count, int index)
{
  if(count == 1)
    fprintf(stderr, RED "[myshell] Error: Exec need parameters!\n"); 
  else{
    char ** cmds_for_exec = &(cmds[index + 1]);
    if(execvp(cmds[index + 1],cmds_for_exec)!=0)
      fprintf(stderr, RED "[myshell] Error: Can not find the cmd!\n"); 
  }
}

 
void Set_func(int count, int index)
{
  if(count == 1)
    Env_func();
   
  else if(count == 3){
    char* environ = getenv(cmds[index + 1]);
     
    if(!environ)
      fprintf(stderr, RED "[myshell] Error: Can not find the environironment variable!\n"); 
     
    else
      setenv(cmds[index + 1],cmds[index + 2],1);
  }
   
  else
    fprintf(stderr, RED "[myshell] Error: Please check your parameters!\n"); 
}

 
void Unset_func(int count, int index)
{
   
  if(count == 2){
    char* environ = getenv(cmds[index + 1]);
     
    if(!environ)
      fprintf(stderr, RED "[myshell] Error: Can not find the environironment variable!\n"); 
      
    else
      setenv(cmds[index + 1],"",1);
  }
   
  else
    fprintf(stderr, RED "[myshell] Error: Please check your parameters!\n"); 
}

 
int Isnum(int index)
{
  for(int i=0;i<strlen(cmds[index + 1]);i++)
     
    if((!isdigit(cmds[index + 1][i]) && i != 0) || (i == 0 && cmds[index + 1][i]  != '-' && !isdigit(cmds[index + 1][i]))){
      return 1;
    }
    
   
  for(int i=0;i<strlen(cmds[index + 3]);i++)
    if((!isdigit(cmds[index + 3][i]) && i != 0) || (i == 0 && cmds[index + 3][i]  != '-' && !isdigit(cmds[index + 3][i]))){
      return 1;
    }
     
  return 0;       
}

 
void Test_func(int count, int index)
{
   
  int flag = 0;
   
  if(count == 4){
     
    if(strcmp(cmds[index + 2],"=") == 0){
      if(strcmp(cmds[index + 1],cmds[index + 3]) == 0)
        printf("True\n");
      else
        printf("False\n");
    }
     
    if(strcmp(cmds[index + 2],"!=") == 0){
      if(strcmp(cmds[index + 1],cmds[index + 3]) == 0)
        printf("False\n");
      else
        printf("True\n");
    }
    if(strcmp(cmds[index + 2],"-eq") == 0){
      flag = Isnum(index);
      if(!flag){
        if(atoi(cmds[index + 1]) == atoi(cmds[index + 3]))
          printf("True\n");
        else
          printf("False\n");
      }
      else
        fprintf(stderr, RED "[myshell] Error: When you use -eq, parameters should be number!\n");      
    }
    if(strcmp(cmds[index + 2],"-ge") == 0){
      flag = Isnum(index);
      if(!flag){
        if(atoi(cmds[index + 1]) >= atoi(cmds[index + 3]))
          printf("True\n");
        else
          printf("False\n");
      }
      else
        fprintf(stderr, RED "[myshell] Error: When you use -gt, parameters should be number!\n"); 
    }
    if(strcmp(cmds[index + 2],"-gt") == 0){
      flag = Isnum(index);
      if(!flag){
        if(atoi(cmds[index + 1]) > atoi(cmds[index + 3]))
          printf("True\n");
        else
          printf("False\n");
      }
      else
        fprintf(stderr, RED "[myshell] Error: When you use -gt, parameters should be number!\n"); 
    }
    if(strcmp(cmds[index + 2],"-le") == 0){
      flag = Isnum(index);
      if(!flag){
        if(atoi(cmds[index + 1]) <= atoi(cmds[index + 3]))
          printf("True\n");
        else
          printf("False\n");
      }
      else
        fprintf(stderr, RED "[myshell] Error: When you use -le, parameters should be number!\n"); 
    }
    if(strcmp(cmds[index + 2],"-lt") == 0){
      flag = Isnum(index);
      if(!flag){
        if(atoi(cmds[index + 1]) < atoi(cmds[index + 3]))
          printf("True\n");
        else
          printf("False\n");
      }
      else
        fprintf(stderr, RED "[myshell] Error: When you use -lt, parameters should be number!\n"); 
    }
    if(strcmp(cmds[index + 2],"-ne") == 0){
      flag = Isnum(index);
      if(!flag){
        if(atoi(cmds[index + 1]) != atoi(cmds[index + 3]))
          printf("True\n");
        else
          printf("False\n");
      }
      else
        fprintf(stderr, RED "[myshell] Error: When you use -ne, parameters should be number!\n"); 
    }           
  }
  else
    fprintf(stderr, RED "[myshell] Error: The number of parameters should be exactly 3!\n");  
}

void Shift_func(int count, int index)
{
   
  if(count == 1){  
     
    Read_cmd(NULL);
     
    int flag = Split_cmd();
     
    if(flag == 1)
      ;    
     
    else if(flag == 2){
      fprintf(stderr, RED "[myshell] Error: Parameters are too much!\n");
    }
     
    else{
      for(int i=1;i<cmd_count;i++){
        printf("%s ",cmds[i]);
      }
      printf("\n");
    }    
  }
   
  else if(count == 2){
    int flag = 0;
    for(int i=0;i<strlen(cmds[index + 1]);i++){
      if(!isdigit(cmds[index + 1][i])){
        flag = 1;
        break;
      }
    }
    if(flag)
      fprintf(stderr, RED "[myshell] Error: Parameter should be number!\n");
    else{
      int shift_num = atoi(cmds[index + 1]);
       
      Read_cmd(NULL);
       
      int flag = Split_cmd();
       
      if(flag == 1)
        ;          
       
      else if(flag == 2){
        fprintf(stderr, RED "[myshell] Error: Parameters are too much!\n");
      }
       
      else{
        for(int i=shift_num;i<cmd_count;i++){
          printf("%s ",cmds[i]);
        }
        printf("\n");
      } 
    }       
  }
   
  else
    fprintf(stderr, RED "[myshell] Error: The number of parameters should be exactly 0 or 1!\n");
}


void History_func(int count, int index){
      
    FILE *history_file = fopen("history.txt", "r");
    if (history_file == NULL) {
        fprintf(stderr, RED "[myshell] Error: Failed to open history file!\n");
        return;
    }

      
    int history_count = 0;
    char ch;
    while((ch = fgetc(history_file)) != EOF){
        if(ch == '\n'){
            history_count++;
        }
    }
    rewind(history_file);   

      
    if(count == 1){
        char line[MAX_HISTORY_LENGTH];
        int i=1;
        while (fgets(line, MAX_HISTORY_LENGTH, history_file) != NULL) {
            printf("%d %s", i++,line);
        }
    }
      
    else if(count == 2){
          
        int n = atoi(cmds[index + 1]);
        if(n > 0 && n <= history_count){
            char line[MAX_HISTORY_LENGTH];
            int line_count = 0;
            int i=1;
            while (fgets(line, MAX_HISTORY_LENGTH, history_file) != NULL) {
                if (line_count >= history_count - n) {
                    printf("%d %s", i++,line);
                }
                line_count++;
            }
        } else {
            fprintf(stderr, RED "[myshell] Error: Invalid history index!\n");
        }
    }
      
    else {
        fprintf(stderr, RED "[myshell] Error: Too many parameters for history cmd!\n");
    }

    fclose(history_file);
}
void UnAlias_func(int count, int index) {

    FILE* file, * temp_file;
    char line[1024];
    int found = 0;
    char* alias = cmds[index + 1];
    file = fopen("/home/rcy/m_shell/alias.txt", "r");
    if (file == NULL) {

        printf("无法打开文件");

        return 1;

    }
    temp_file = fopen("/home/rcy/m_shell/temp.txt", "w");

    if (temp_file == NULL) {

        printf("无法创建临时文件");

        fclose(file);

        return 1;

    }
    while (fgets(line, sizeof(line), file)) {

        if (strstr(line, alias) == NULL) {
            fputs(line, temp_file);
        }
        else {
            found = 1;
        }

    }
    fclose(file);
    fclose(temp_file);
    if (found) {
        printf("已删除%s命令的别名！\n", alias);
    }
    else
    {
        printf("未寻找到%s命令的别名！", alias);
    }
    remove("/home/rcy/m_shell/alias.txt");
    rename("/home/rcy/m_shell/temp.txt", "/home/rcy/m_shell/alias.txt");
}
void Alias_func(int count, int index) {
      
    if (count < 2) {
        fprintf(stderr, RED "[myshell] Error: Insufficient parameters for alias cmd!\n");
        return;
    }
    char* alias = cmds[index + 1];
    alias[strlen(alias) - 1] = '\0';
      
    char cmd[MAX_cmd_LENGTH];
    cmd[0] = '\0';
    for (int i = index + 2; i < cmd_count; i++) {
        strcat(cmd, cmds[i]);
        if (i < cmd_count - 1) {
            strcat(cmd, " ");
        }
    }

      
    if (cmd[0] == '\'' && cmd[strlen(cmd) - 1] == '\'') {
          
        memmove(cmd, cmd + 1, strlen(cmd) - 2);
        cmd[strlen(cmd) - 2] = '\0';
    }
      
    FILE* alias_file = fopen("alias.txt", "a");
    if (alias_file == NULL) {
        fprintf(stderr, RED "[myshell] Error: Failed to open alias file!\n");
        return;
    }

     
    fprintf(alias_file, "%s  %s\n", alias, cmd);


    printf("Alias '%s' set to '%s'\n", alias, cmd);
    fclose(alias_file);
}

 
void Help_func()
{
  printf("欢迎查看myshell的用户手册！\n");
  printf("\n");
 printf("*******************************************************************************\n");
  printf("Chapter 1: 内建命令的使用\n\n");
 
   printf("1. history\n");
   printf("命令作用：  显示最近执行的命令历史\n");
   printf("使用示例：  history 或 history n\n");
   printf("参数个数：  零个或一个参数（需要查看的命令历史条数）\n");
   printf("\n");

   printf("2. alias\n");
   printf("命令作用：  为复杂的命令或命令序列创建简短的别名\n");
   printf("使用示例：  alias 别名='命令'\n");
   printf("参数个数：  两个参数（别名及其代表的命令）\n");
   printf("\n");

   printf("3. alias\n");
   printf("命令作用：  列出当前系统中定义的所有别名\n");
   printf("使用示例：  alias\n");
   printf("参数个数：  无需参数\n");
   printf("\n");

   printf("4. unalias\n");
   printf("命令作用：  删除指定的别名\n");
   printf("使用示例：  unalias 别名\n");
   printf("参数个数：  一个参数（要取消的别名）\n");
   printf("\n");

   printf("5. clr\n");
   printf("命令作用：  清除终端屏幕上的所有文本\n");
   printf("使用示例：  clr\n");
   printf("参数个数：  无需参数\n");
   printf("\n");

   printf("6. pwd\n");
   printf("命令作用：  输出当前工作目录的绝对路径\n");
   printf("使用示例：  pwd\n");
   printf("参数个数：  无需参数\n");
   printf("\n");

   printf("7. quit\n");
   printf("命令作用：  终止 myshell 程序的运行\n");
   printf("使用示例：  quit\n");
   printf("参数个数：  无需参数\n");
   printf("\n");

   printf("8. help\n");
   printf("命令作用：  提供 myshell 的帮助信息或用户手册\n");
   printf("使用示例：  help\n");
   printf("参数个数：  无需参数\n");
   printf("\n");

   printf("9. environ\n");
   printf("命令作用：  列出所有环境变量的名称和值\n");
   printf("使用示例：  environ\n");
   printf("参数个数：  无需参数\n");
   printf("\n");

    printf("10. set\n");
    printf("命令作用：  无参数时显示所有环境变量；有参数时设置环境变量的值\n");
    printf("使用示例：  set 或 set VAR value\n");
    printf("参数个数：  无需参数，或两个参数（变量名和值）\n");
    printf("\n");

    printf("11. jobs\n");
    printf("命令作用：  列出所有后台运行的进程\n");
    printf("使用示例：  jobs\n");
    printf("参数个数：  无需参数\n");
    printf("\n");

    printf("12. time\n");
    printf("命令作用：  打印出当前的系统时间\n");
    printf("使用示例：  time\n");
    printf("参数个数：  无需参数\n");
    printf("\n");

    printf("13. cd\n");
    printf("命令作用：  无参数时显示当前目录；有参数时切换到指定目录\n");
    printf("使用示例：  cd 或 cd path\n");
    printf("参数个数：  无需参数，或一个参数（目标路径）\n");
    printf("\n");

    printf("14. exec\n");
    printf("命令作用：  用新的进程替换当前 shell 进程\n");
    printf("使用示例：  exec command\n");
    printf("参数个数：  一个参数（要执行的命令）\n");
    printf("\n");

    printf("15. exit\n");
    printf("命令作用：  终止当前进程的执行\n");
    printf("使用示例：  exit\n");
    printf("参数个数：  无需参数\n");
    printf("\n");

    printf("16. dir\n");
    printf("命令作用：  无参数时显示当前目录内容；有参数时显示指定目录内容\n");
    printf("使用示例：  dir 或 dir path\n");
    printf("参数个数：  无需参数，或一个参数（目录路径）\n");
    printf("\n");

    printf("17. echo\n");
    printf("命令作用：  无参数时输出空行；有参数时输出提供的文本\n");
    printf("使用示例：  echo 或 echo text\n");
    printf("参数个数：  无需参数，或任意数量的参数\n");
    printf("\n");

    printf("18. unset\n");
    printf("命令作用：  删除指定的环境变量\n");
    printf("使用示例：  unset VAR\n");
    printf("参数个数：  一个参数（环境变量名）\n");
    printf("\n");

    printf("19. bg\n");
    printf("命令作用：  将最近的挂起进程转为后台运行\n");
    printf("使用示例：  bg\n");
    printf("参数个数：  无需参数\n");
    printf("\n");

    printf("20. fg\n");
    printf("命令作用：  将最近的后台任务调至前台运行\n");
    printf("使用示例：  fg\n");
    printf("参数个数：  无需参数\n");
    printf("\n");

    printf("21. umask\n");
    printf("命令作用：  无参数时显示当前掩码；有参数时设置新的文件权限掩码\n");
    printf("使用示例：  umask 或 umask value\n");
    printf("参数个数：  无需参数，或一个参数（新的掩码值）\n");
    printf("\n");

    printf("22. shift\n");
    printf("命令作用：  左移命令行参数，默认移动一位，或移动指定数量的位置\n");
    printf("使用示例：  shift 或 shift count\n");
    printf("参数个数：  无需参数，或一个参数（移动的位数）\n");
    printf("\n");

    printf("23. test\n");
    printf("命令作用：  进行字符串或数字的比较测试\n");
    printf("使用示例：  test str1 op str2 或 test num1 op num2\n");
    printf("参数个数：  三个参数（操作数1，比较操作符，操作数2）\n");
  printf("*******************************************************************************\n");
  printf("\n\n");
  
  printf("*******************************************************************************\n");
  printf("Chapter 2: 外部命令的执行\n\n");
  printf("命令作用：  执行非内建命令，如 ls 或 gedit\n");
  printf("使用示例： ls -l\n");
  printf("使用示例： gedit test.txt\n");
  printf("*******************************************************************************\n");
  printf("\n\n");
  
  printf("*******************************************************************************\n");
  printf("Chapter 3: 脚本文件的执行\n\n");
  printf("命令作用：  从脚本文件中读取并执行命令\n");
  printf("使用示例：  myshell test.sh\n");
  printf("*******************************************************************************\n");
  printf("\n\n");
  
  printf("*******************************************************************************\n");
  printf("Chapter 4: I/O重定向\n\n");
  printf("命令作用：  改变命令的输入输出来源或去向\n");
  printf("使用示例：  wc < test1.txt >> test2.txt\n");
  printf("*******************************************************************************\n");
  printf("\n\n");
  
  printf("*******************************************************************************\n");
  printf("Chapter 5: 后台程序执行\n\n");
  printf("命令作用：  在后台执行程序，不阻塞主进程\n");
  printf("使用示例：  sleep 5 &\n");
  printf("*******************************************************************************\n");
  printf("\n\n");
  
  printf("*******************************************************************************\n");
  printf("Chapter 6: 管道操作\n\n");
  printf("命令作用：  将一个命令的输出作为另一个命令的输入\n");
  printf("使用示例：  ls | wc\n");
  printf("*******************************************************************************\n");
  printf("\n\n");
  
  printf("*******************************************************************************\n");
  printf("Chapter 7: 历史指令\n\n");
  printf("命令作用：  允许用户重复执行之前输入的命令\n");
  printf("使用示例：\n");
  printf("!n：运行历史记录中的第 n 条命令。\n");
  printf("!!：运行最近一次执行的命令，即前一条命令。\n");
  printf("!?String?：运行包含 String 字符串的历史命令。\n");
  printf("*******************************************************************************\n");
  printf("\n\n");

  printf("*******************************************************************************\n");
  printf("Chapter 8: 程序环境\n\n");
  printf("简单描述： myshell利用extern直接使用Linux系统保存的环境变量environ，要显示所有的环境变量只需要循环打印即可，修改环境变量则使用getenv()，setenv()等函数即可实现。此外还在程序开头利用shmget()函数创建了一段共享内存用于存储后台进程表的相关信息，共享内存在连接之后可以被所有进程访问到，所以使用共享内存存储后台进程表是较合理的选择\n\n");
  printf("*******************************************************************************\n");
  printf("\n");
 
}

 
void Init_joblist()
{
  int shmID = shmget((key_t)1234, sizeof(job)*MAX_JOB_NUM + sizeof(int), 0666 | IPC_CREAT);
  if(shmID == -1){
    fprintf(stderr, RED "[myshell] Error: Create shared memory failed!\n"); 
    exit(1);   
  }
  
  void* shm = shmat(shmID, 0, 0);
  if(shm == (void*)-1 ){
    fprintf(stderr, RED "[myshell] Error: Connect shared memory failed!\n"); 
    exit(1);   
  }
  job_shmID = shmID;
  jobs = (job*)shm;
  job_count = (int*)((char*)shm + sizeof(jobs)*MAX_JOB_NUM);

  
  for(int i=0; i<MAX_JOB_NUM; i++)
    jobs[i].pid = -1;
  
  jobs[0].pid = getpid();
  strcpy(jobs[0].jobname, "myshell");
  jobs[0].type = FG;
  jobs[0].status = RUN;
  
  *job_count = 1;
}

 
job* Add_job(pid_t pid, char* jobname, int type, int status)
{
  int count = *job_count;
   
  if(count == MAX_JOB_NUM){
    fprintf(stderr, RED "[myshell] Error: The job list is full!\n");
    exit(1);
  } 
  
  jobs[count].pid = pid;
  jobs[count].type = type;
  jobs[count].status = status;
  strcpy(jobs[count].jobname, jobname);
   
  *job_count = count + 1;
   
  return (jobs + count);
}

 
void Del_job(pid_t pid)
{
  int i;
  int count = *job_count;
   
  for(i=0; i<count; i++){
     
    if(pid == jobs[i].pid)
      break;
  }
  
   
  if(i < count){
     
    for(; i<count-1; i++)
      jobs[i] = jobs[i+1];
     
    *job_count = count - 1;
  }
}

 
void Free_joblist()
{
   
  if(shmdt((void*)jobs) == -1){
    fprintf(stderr, RED "[myshell] Error: Disconnect shared memory failed!\n");
    exit(1);
  }
  
   
  if(shmctl(job_shmID, IPC_RMID, 0) == -1){
    fprintf(stderr, RED "[myshell] Error: Delete shared memory failed!\n");
    exit(1);
  }
}

 
void Jobs_func()
{
   
  int count = *job_count;
   
  int done_cnt = 0;
  int done_pid[MAX_JOB_NUM];
   
  int bg_cnt = 0;
    
     
    for(int i=0; i<count; i++){
       
      if(jobs[i].type == BG){
         
        if(jobs[i].status == SUSPEND)
          printf("[%d]  %d  SUSPEND		  %s\n",bg_cnt+1,jobs[i].pid,jobs[i].jobname);
          
         
        else if(jobs[i].status == RUN)
          printf("[%d]  %d  RUNNING		  %s\n",bg_cnt+1,jobs[i].pid,jobs[i].jobname);
          
         
        else{
          printf("[%d]  %d  DONE		  %s\n",bg_cnt+1,jobs[i].pid,jobs[i].jobname);
          done_pid[done_cnt] = jobs[i].pid;
          done_cnt++;     
        }  
         
        bg_cnt++;    
      }

    }
  
     
  if(bg_cnt == 0)
  printf("No background job currently!\n");
  
    
  for(int j=0;j<done_cnt;j++)
    Del_job(done_pid[j]);

}

 
void To_fg_func()
{
   
  int count = *job_count;
  int status;
   
  int bg_cnt = 0;
   
  int last_BG;
  
   
  for(int i=0; i<count ;i++)
    if(jobs[i].type == BG){
       
      bg_cnt++;
       
      last_BG = i;
    }
      
   
  if(bg_cnt == 0)
    printf("No background job currently!\n");
    
   
  else{
     
    printf("%s\n",jobs[last_BG].jobname);
     
    if(jobs[last_BG].status == SUSPEND){
       
      jobs[last_BG].type = FG; 
       
      jobs[last_BG].status = RUN;
       
      kill(jobs[last_BG].pid, SIGCONT);
       
      waitpid(jobs[last_BG].pid,&status,0);
    }
    
     
    else if(jobs[last_BG].status == RUN){
       
      jobs[last_BG].type = FG;  
       
      waitpid(jobs[last_BG].pid,&status,0);
    }
  }
}

 
void To_bg_func()
{
   
  int count = *job_count; 
   
  int bg_cnt = 0;
  int i;
   
  for(i=0; i<count; i++){
     
    if(jobs[i].type == BG){
       
      if(jobs[i].pid > 0 && jobs[i].status == SUSPEND){
         
        jobs[i].status = RUN;
         
        kill(jobs[i].pid, SIGCONT);
         
        printf("[%d] %s &\n",bg_cnt+1,jobs[i].jobname);
        break;
      }
      bg_cnt++;    
    }

  }
  
   
  if(i == count)
    printf("No suspend job in the background now!\n");
}

